<?php

/**
 * Элемент формы.
 *
 */
abstract class Kernel_Form_Element_Abstract extends Kernel_Component {

    /**
     * Заголовок. Если не указан — формируется из наименования элемента.
     *
     * @var string
     */
    public $caption;

    /**
     * Обязательно ли поле для заполнения. В случае, если в качестве значения
     * указана строка, она используется как сообщение об ошибке. Иначе
     * используется стандартное сообщение.
     *
     * @var mixed (boolean/string)
     */
    public $required = false;

    /**
     * Поле только для чтения. Его значение формируется автоматически, и может
     * быть доступно таким же образом, как и значение, полученное из
     * пользовательского запроса.
     *
     * @var boolean
     */
    public $readonly = false;

    /**
     * Отображать ли элемент в автоматически сгенерированной форме.
     *
     * @var boolean
     */
    public $display = true;

    /**
     * Примечание к элементу.
     *
     * @var string
     */
    public $note;

    /**
     * Описания валидаторов элемента.
     *
     * @var array
     */
    public $validators = array();

    /**
     * Значение элемента.
     *
     * @var mixed
     */
    public $value;

    /**
     * Нужно ли обрезать значение для текстовых полей.
     *
     * @var boolean
     */
    public $trim;

    /**
     * Наименование шаблона, по которому нужно отрисовать элемент в форме.
     *
     * @var string
     */
    public $template;

    /**
     * Возвращает значение элемента.
     *
     * @return  mixed
     */
    public function getValue() {
        return $this->_getParam('value');
    }

    /**
     * Возвращает, может ли значение элемента быть отредактировано пользователем.
     *
     * @return  boolean
     */
    public function isEditable() {
        return $this->display && !$this->readonly;
    }

    /**
     * Возвращает, является ли поле обязательным для заполнения.
     *
     * @return  boolean
     */
    public function isRequired() {
        return $this->required;
    }

    /**
     * Устанавливает значение элемента.
     *
     * @param   mixed   $value
     */
    public function setValue($value) {
        $this->value = is_string($value) && $this->trim ? trim($value) : $value;
    }

    /**
     * Возвращает описание элемента для шаблона.
     *
     * @return  array
     */
    public function getParams() {
        if (!$this->display) {
            return false;
        }
        $params = array();
        foreach (array_keys(get_class_vars(get_class($this))) as $param) {
            $params[$param] = $this->_getParam($param);
        }
        return $params;
    }

    /**
     * Возвращает шаблон поля для шаблона.
     *
     * @return  string
     */
    protected function _getTemplate() {
        return null !== $this->template ? $this->template : $this->_getName();
    }

    /**
     * Возвращает значение указанного параметра элемента.
     *
     * @param   string  $param
     * @return  mixed
     */
    private function _getParam($param) {
        return method_exists($this, $method = '_get' . ucfirst($param))
            ? $this->$method() : $this->$param;
    }
}
